home *** CD-ROM | disk | FTP | other *** search
- {$D+,R-,S-}
- UNIT ObjectA;
-
- {
- Rob Rosenberger CIS: 74017,1344
- Barn Owl Software VOX: (618) 632-7345
- P.O. Box #74 BBS: (618) 398-5703
- O'Fallon, IL 62269 HST: (618) 398-2305
-
- This Turbo Pascal 5.5 unit builds on the OBJECTS.PAS file on disk three
- of the TP package. The Objects unit provides some excellent linked-list
- capabilities, but it doesn't allow arbitrary placement of a node on the list.
- This unit offers a decendent, LinkList, which provides two extra methods:
- LinkList.Before, to place a node just before some other node in the list, and
- LinkList.After, to place a node just after some other node in the list.
- LinkList.Init and LinkList.Done are included because the TP5.5 OOP guide
- recommends these common procedures. The List ancestor calls them Clear and
- Delete, respectively, which I found extremely odd since _Borland_ is the one
- calling for a standard set of method identifiers....
-
- Version 1.00: released to the public domain on 8 July 1989.
- See above for the reason this was developed.
-
- Version 1.01: released to the public domain on 17 August 1989.
- Lavern Ogden discovered an endless loop in the Total() function. This was
- due to my using LinkList.Next instead of LinkList.Next(). I fault Borland for
- this error -- there are two "Next" possibilities. Shame shame!
- Added a new function, Specific(), which returns a NodePtr to the nth node
- in the list. This will be very handy for people who use TurboPower Software's
- TPPICK unit from their TPRO5 toolkit.}
-
-
- INTERFACE {section}
-
-
- USES
- Objects;
-
- TYPE
- LinkList
- = OBJECT(List)
- PROCEDURE Init;
- PROCEDURE Done;
-
- PROCEDURE Before(TheNode : NodePtr;
- BeforeNode : NodePtr);
- PROCEDURE After (TheNode : NodePtr;
- AfterNode : NodePtr);
-
- FUNCTION Specific(NodePos : LONGINT) : NodePtr;
- FUNCTION Total(TheNode : NodePtr) : LONGINT;
- END;
-
-
- IMPLEMENTATION {section}
-
-
- {============================================================================}
- PROCEDURE LinkList.Init;
-
- {This procedure initializes the LinkList.}
-
- BEGIN {LinkList.Init}
- Clear
- END; {LinkList.Init}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE LinkList.Done;
-
- {This procedure deletes all nodes from the list.}
-
- BEGIN {LinkList.Done}
- Delete
- END; {LinkList.Done}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE LinkList.Before(TheNode : NodePtr;
- BeforeNode : NodePtr);
-
- {Places TheNode in the LinkList just before BeforeNode.}
-
- BEGIN {LinkList.Before}
- IF (TheNode = NIL)
- THEN
- EXIT {there's nothing to add to our LinkList}
- ELSE
- IF ((BeforeNode = NIL)
- OR (BeforeNode^.Prev = NIL))
- THEN {append as first node on the LinkList}
- Append(TheNode)
- ELSE
- BEGIN
- TheNode^.Next := BeforeNode;
- BeforeNode^.Prev^.Next := TheNode
- END
- END; {LinkList.Before}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE LinkList.After(TheNode : NodePtr;
- AfterNode : NodePtr);
-
- {Places TheNode in the LinkList just after AfterNode.}
-
- BEGIN {LinkList.After}
- IF (TheNode = NIL)
- THEN
- EXIT {there's nothing to add to our LinkList}
- ELSE
- IF ((AfterNode = NIL)
- OR (AfterNode^.Next = NIL))
- THEN {Insert as last node on the LinkList}
- Insert(TheNode)
- ELSE
- BEGIN
- TheNode^.Next := AfterNode^.Next;
- AfterNode^.Next := TheNode
- END
- END; {LinkList.After}
- {============================================================================}
-
- {============================================================================}
- FUNCTION LinkList.Specific(NodePos : LONGINT) : NodePtr;
-
- {Returns the NodePtr to the nth node in the list, represented by NodePos.
- The returned value will be NIL if NodePos <= 0, or if it is > Total.}
-
- VAR
- TempNodePtr : NodePtr;
- Index : LONGINT;
-
- BEGIN {LinkList.Specific}
- {Make sure we have a valid NodePos value.}
- IF ((NodePos <= 0) OR (NodePos > Total(First)))
- THEN
- Specific := NIL
- ELSE
- BEGIN
- TempNodePtr := First;
- Index := 1;
-
- WHILE (Index < NodePos)
- DO BEGIN
- TempNodePtr := Next(TempNodePtr);
- INC(Index)
- END;
-
- Specific := TempNodePtr
- END
- END; {LinkList.Specific}
- {============================================================================}
-
- {============================================================================}
- FUNCTION LinkList.Total(TheNode : NodePtr) : LONGINT;
-
- {This function returns a number corresponding to the number of nodes on the
- LinkList. It starts counting from TheNode^. Therefore, to get a total count
- of all nodes on the LinkList, use LinkListVar.Total(LinkListVar.First).}
-
- VAR
- TempLongint : LONGINT;
-
- BEGIN {LinkList.Total}
- {Initialize.}
- TempLongint := 0;
-
- IF (TheNode = NIL)
- THEN
- {Do nothing.}
- ELSE
- REPEAT
- INC(TempLongint);
- TheNode := Next(TheNode)
- UNTIL (TheNode = NIL);
-
- Total := TempLongint
- END; {LinkList.Total}
- {============================================================================}
-
-
- END. {ObjectA}